<template>
  <div class="swiper" ref="swiper">
    <ul
      class="swiper-grounp"
      ref="swiperGroup"
      :style="{
        transform: `translate3d(${targeX}px, 0, 0)`,
        transition:isMovingToX? `transform ${autoPlaySpeed}ms cubic-bezier(0, 0, 0.25, 1)`:''
      }"
      @touchstart="touchstartFn"
      @touchmove="touchmoveFn"
      @touchend="touchendFn"
      @transitionend="transitionEndFn"
    >
      <li
        class="swiper-item"
        v-for="(item,i) in swiperImages"
        :key="i"
        :style="item?{backgroundImage: 'url(' + item.src + ')'}:{}"
      ></li>
    </ul>
    <div class="navigate" ref="navigate" v-if="ifDots"></div>
  </div>
</template>

<script >
export default {
  props: {
    imageList: {
      type: Array,
      default: () => {
        return [];
      }
    },
    swiperItemWidth: {
      type: Number,
      default: document.body.clientWidth
    },
    swiperItemHeight: {
      type: Number,
      default: 300
    },
    ifAutoPlay: {
      type: Boolean,
      default: true
    },
    autoPlayDelay: {
      type: Number,
      default: 1000
    },
    autoPlaySpeed: {
      type: Number,
      default: 350,
      validator(val) {
        return val > 0;
      }
    },
    ifDots: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      swiperImages: [],
      swiperIndex: 1,
      mainTimeOut: null,
      targeX: 0,
      temporaryX: null,
      isMovingToX: false,
      startX: null,
      endX: null,
      noImgFlag:false,
    };
  },
  watch: {
    swiperIndex(val) {
      if (this.ifDots) {
        if (val >= 1 && val <= this.$refs.navigate.children.length) {
          this.dotActiveStyle(this.$refs.navigate.children[val - 1]);
        }
      }
      this.$emit('itemChange',this.getTrueActiveIndex(val),!this.noImgFlag?this.swiperImages[val].url?this.swiperImages[val].url:'':'')
    }
  },
  created() {
    if (this.imageList.length > 1) {
      this.swiperImages = this.imageList
        .slice(-1)
        .concat(this.imageList, this.imageList.slice(0, 1));
    } else {
      this.swiperImages = this.imageList;
    }
  },
  mounted() {
    this.initSwiper();
    this.ifAutoPlay ? this.startAutoMove() : () => {};
    this.ifDots
      ? this.dotActiveStyle(this.$refs.navigate.children[0])
      : () => {};
  },
  destroyed() {
    clearTimeout(this.mainTimeOut);
  },
  methods: {
    initSwiper() {
      const MOVER = this.$refs.swiperGroup;
      this.initImg(MOVER);
      this.$refs.swiper.style.width = this.swiperItemWidth + "px";
      this.$refs.swiper.style.height = this.swiperItemHeight + "px";
      MOVER.style.width =
        (this.swiperImages.length + 2) * this.swiperItemWidth + "px";
      for (let i = 0; i < MOVER.children.length; i++) {
        let linkTo = !this.noImgFlag?this.swiperImages[i].url ? this.swiperImages[i].url : this.getTrueActiveIndex(i):()=>{};
        MOVER.children[i].addEventListener("click", e => {
          this.itemClick(e, linkTo);
        });
        MOVER.children[i].style.width = this.swiperItemWidth + "px";
        if (i !== 0 && i !== MOVER.children.length - 1 && this.ifDots) {
          this.initDots(i);
        }
      }
      if (this.swiperImages.length > 1) {
        this.targeX = this.temporaryX = -this.swiperItemWidth;
      }
    },
    initImg(MOVER) {
      if (this.swiperImages.length === 0) {
        for (let i = 0; i < 3; i++) {
          let pic = document.createElement("li");
          pic.classList.add("swiper-item");
          pic.classList.add(`default-item-${i}`);
          this.$refs.swiperGroup.appendChild(pic);
        }
        let head = MOVER.children[0].cloneNode(true);
        let tail = MOVER.children[2].cloneNode(true);
        MOVER.appendChild(head);
        MOVER.insertBefore(tail, MOVER.children[0]);
        this.swiperImages.length = 5;
        this.noImgFlag=true;
      }
    },
    initDots(i) {
      let dot = document.createElement("div");
      dot.addEventListener("click", e => {
        this.navigateToPic(e);
      });
      dot.setAttribute("id", i);
      dot.classList.add("dots");
      this.$refs.navigate.appendChild(dot);
    },
    startAutoMove() {
      clearTimeout(this.mainTimeOut);
      this.mainTimeOut = setTimeout(() => {
        this.stepMove(++this.swiperIndex);
      }, this.autoPlayDelay);
    },
    transitionEndFn(e) {
      if (this.isMovingToX) {
        this.isMovingToX = false;
        this.stepMove(this.getTrueActiveIndex(), 0);
        this.ifAutoPlay ? this.startAutoMove() : () => {}; //是否继续开启下一张位移
      }
    },
    getTrueActiveIndex() {
      if (this.swiperImages.length === 1) return 0;
      if (this.swiperIndex >= this.swiperImages.length - 1) return 1;
      if (this.swiperIndex <= 0) return this.swiperImages.length - 2;
      return this.swiperIndex;
    },
    touchstartFn(e) {
      clearTimeout(this.mainTimeOut);
      if (this.isMovingToX) {
        this.isMovingToX = false;
        this.targeX = this.temporaryX =
          this.$refs.swiperGroup.getBoundingClientRect().left -
          this.$refs.swiper.getBoundingClientRect().left;
      }
      this.startX = e.touches[0].clientX;
    },
    touchmoveFn(e) {
      if (this.swiperImages.lengh === 1) {
        this.targeX =
          (e.touches[0].clientX - this.startX) * 0.1 + this.temporaryX;
      } else {
        let temp = e.touches[0].clientX - this.startX + this.temporaryX;
        if (temp > 0) {
          this.startX = e.touches[0].clientX;
          this.targeX = this.temporaryX =
            -this.swiperItemWidth * (this.swiperImages.length - 2);
        } else if (
          this.targeX <
          -this.swiperItemWidth * (this.swiperImages.length - 1)
        ) {
          this.startX = e.touches[0].clientX;
          this.targeX = this.temporaryX = -this.swiperItemWidth;
        }
        this.targeX = temp;
      }
    },
    touchendFn(e) {
      this.endX = e.changedTouches[0].clientX;
      if (this.endX - this.startX > 50) {
        this.stepMove(--this.swiperIndex);
      } else if (this.endX - this.startX < -50) {
        this.stepMove(++this.swiperIndex);
      }
    },
    navigateToPic(e) {
      this.stepMove(e.target.id);
      this.dotActiveStyle(e.target);
    },
    dotActiveStyle(elem) {
      const CHILD = this.$refs.navigate.children;
      for (let i = 0; i < CHILD.length; i++) {
        CHILD[i].classList.remove("dots__leave");
        if (CHILD[i].classList.contains("dots__active")) {
          CHILD[i].classList.remove("dots__active");
          CHILD[i].classList.add("dots__leave");
        }
      }
      elem ? elem.classList.add("dots__active") : () => {};
    },
    stepMove(index, flag = 1) {
      this.swiperIndex = index;
      this.targeX = this.temporaryX = -this.swiperItemWidth * this.swiperIndex;
      flag ? (this.isMovingToX = true) : () => {};
    },
    itemClick(e, url) {
      this.$emit("itemClick", url);
    }
  }
};
</script>
<style >
.swiper-item {
  float: left;
  height: 100%;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}
.default-item-0 {
  background: rgba(203, 31, 209, 0.596);
}
.default-item-1 {
  background: rgba(209, 31, 70, 0.596);
}
.default-item-2 {
  background: rgba(108, 31, 209, 0.596);
}
.dots {
  background: rgba(148, 142, 142, 0.28);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 10px;
}
.dots__active {
  animation: dotenter 0.5s ease-in;
  background: rgba(255, 0, 0, 0.58);
}
.dots__leave {
  animation: dotleave 0.5s ease-out;
}
@keyframes dotenter {
  0% {
    background: rgba(148, 142, 142, 0.28);
  }
  100% {
    background: rgba(255, 0, 0, 0.58);
  }
}
@keyframes dotleave {
  0% {
    background: rgba(255, 0, 0, 0.58);
  }
  100% {
    background: rgba(148, 142, 142, 0.28);
  }
}
</style>
<style lang='scss' scoped>
.swiper {
  margin: 0 auto;
  overflow: hidden;
  position: relative;
  .swiper-grounp {
    height: 100%;
    position: absolute;
    list-style: none;
    padding: 0;
    //animation: switch 5s ease-out infinite;
    .swiper-item {
      float: left;
      height: 100%;
      //  width: calc(100vw);
      background-size: contain;
      background-repeat: no-repeat;
      background-position: center;
    }
  }
  .navigate {
    position: absolute;
    bottom: 10px;
    width: 100%;
    display: flex;
    justify-content: center;
    .dots {
      background: black;
      width: 8px;
      height: 8px;
      border-radius: 50%;
      margin-right: 10px;
    }
  }
  .control {
    .left {
      position: absolute;
      left: 20px;
      top: 50px;
    }
    .right {
      position: absolute;
      right: 20px;
      top: 50px;
    }
  }
}

@keyframes switch {
  0%,
  25% {
    margin-left: 0;
  }
  35%,
  60% {
    margin-left: calc(-100vw);
  }
  70%,
  100% {
    margin-left: calc(-200vw);
  }
}
</style>